home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 002 / emacssrc.arc / EVAL.C < prev    next >
C/C++ Source or Header  |  1987-02-02  |  12KB  |  459 lines

  1. /*    EVAL.C:    Expresion evaluation functions for
  2.         MicroEMACS
  3.  
  4.     written 1986 by Daniel Lawrence                */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "edef.h"
  9. #include    "evar.h"
  10.  
  11. #if    MEGAMAX & ST520
  12. overlay    "eval"
  13. #endif
  14.  
  15. char value[80];        /* buffer to return value in */
  16.  
  17. varinit()        /* initialize the user variable list */
  18.  
  19. {
  20.     register int i;
  21.  
  22.     for (i=0; i < MAXVARS; i++)
  23.         uv[i].u_name[0] = 0;
  24. }
  25.  
  26. char *gtfun(fname)    /* evaluate a function */
  27.  
  28. char *fname;        /* name of function to evaluate */
  29.  
  30. {
  31.     register int fnum;        /* index to function to eval */
  32.     register int status;        /* return status */
  33.     char arg1[NSTRING];        /* value of first argument */
  34.     char arg2[NSTRING];        /* value of second argument */
  35.     char arg3[NSTRING];        /* value of third argument */
  36.     static char result[2 * NSTRING];    /* string result */
  37.  
  38.     /* look the function up in the function table */
  39.     fname[3] = 0;    /* only first 3 chars significant */
  40.     for (fnum = 0; fnum < NFUNCS; fnum++)
  41.         if (strcmp(fname, funcs[fnum].f_name) == 0)
  42.             break;
  43.  
  44.     /* return errorm on a bad reference */
  45.     if (fnum == NFUNCS)
  46.         return(errorm);
  47.  
  48.     /* retrieve the first argument */
  49.     if ((status = macarg(arg1)) != TRUE)
  50.         return(errorm);
  51.  
  52.     /* if needed, retrieve the second argument */
  53.     if (funcs[fnum].f_type >= DYNAMIC) {
  54.         if ((status = macarg(arg2)) != TRUE)
  55.             return(errorm);
  56.  
  57.         /* if needed, retrieve the third argument */
  58.         if (funcs[fnum].f_type >= TRINAMIC)
  59.             if ((status = macarg(arg3)) != TRUE)
  60.                 return(errorm);
  61.     }
  62.  
  63.     /* and now evaluate it! */
  64.     switch (fnum) {
  65.         case UFADD:    return(itoa(atoi(arg1) + atoi(arg2)));
  66.         case UFSUB:    return(itoa(atoi(arg1) - atoi(arg2)));
  67.         case UFTIMES:    return(itoa(atoi(arg1) * atoi(arg2)));
  68.         case UFDIV:    return(itoa(atoi(arg1) / atoi(arg2)));
  69.         case UFMOD:    return(itoa(atoi(arg1) % atoi(arg2)));
  70.         case UFNEG:    return(itoa(-atoi(arg1)));
  71.         case UFCAT:    strcpy(result, arg1);
  72.                 return(strcat(result, arg2));
  73.         case UFLEFT:    return(strncpy(result, arg1, atoi(arg2)));
  74.         case UFRIGHT:    return(strcpy(result, &arg1[atoi(arg2)-1]));
  75.         case UFMID:    return(strncpy(result, &arg1[atoi(arg2)-1],
  76.                     atoi(arg3)));
  77.         case UFNOT:    return(ltos(stol(arg1) == FALSE));
  78.         case UFEQUAL:    return(ltos(atoi(arg1) == atoi(arg2)));
  79.         case UFLESS:    return(ltos(atoi(arg1) < atoi(arg2)));
  80.         case UFGREATER:    return(ltos(atoi(arg1) > atoi(arg2)));
  81.         case UFSEQUAL:    return(ltos(strcmp(arg1, arg2) == 0));
  82.         case UFSLESS:    return(ltos(strcmp(arg1, arg2) < 0));
  83.         case UFSGREAT:    return(ltos(strcmp(arg1, arg2) > 0));
  84.         case UFIND:    return(getval(arg1));
  85.     }
  86.  
  87.     exit(-11);    /* never should get here */
  88. }
  89.  
  90. char *gtusr(vname)    /* look up a user var's value */
  91.  
  92. char *vname;        /* name of user variable to fetch */
  93.  
  94. {
  95.  
  96.     register int vnum;    /* ordinal number of user var */
  97.  
  98.     /* scan the list looking for the user var name */
  99.     for (vnum = 0; vnum < MAXVARS; vnum++)
  100.         if (strcmp(vname, uv[vnum].u_name) == 0)
  101.             break;
  102.  
  103.     /* return errorm on a bad reference */
  104.     if (vnum == MAXVARS)
  105.         return(errorm);
  106.  
  107.     return(uv[vnum].u_value);
  108. }
  109.  
  110. char *gtenv(vname)
  111.  
  112. char *vname;        /* name of environment variable to retrieve */
  113.  
  114. {
  115.     register int vnum;    /* ordinal number of var refrenced */
  116.  
  117.     /* scan the list, looking for the referenced name */
  118.     for (vnum = 0; vnum < NEVARS; vnum++)
  119.         if (strcmp(vname, envars[vnum]) == 0)
  120.             break;
  121.  
  122.     /* return errorm on a bad reference */
  123.     if (vnum == NEVARS)
  124.         return(errorm);
  125.  
  126.     /* otherwise, fetch the appropriate value */
  127.     switch (vnum) {
  128.         case EVFILLCOL:    return(itoa(fillcol));
  129.         case EVPAGELEN:    return(itoa(term.t_nrow + 1));
  130.         case EVCURCOL:    return(itoa(getccol(FALSE)));
  131.         case EVCURLINE: return(itoa(getcline()));
  132.         case EVRAM:    return(itoa((int)(envram / 1024l)));
  133.         case EVFLICKER:    return(ltos(flickcode));
  134.         case EVCURWIDTH:return(itoa(term.t_nrow));
  135.         case EVCBUFNAME:return(curbp->b_bname);
  136.         case EVCFNAME:    return(curbp->b_fname);
  137.         case EVSRES:    return(sres);
  138.         case EVDEBUG:    return(ltos(macbug));
  139.         case EVSTATUS:    return(ltos(cmdstatus));
  140.         case EVPALETTE:    return(palstr);
  141.     }
  142. }
  143.  
  144. int setvar(f, n)        /* set a variable */
  145.  
  146. int f;        /* default flag */
  147. int n;        /* numeric arg (can overide prompted value) */
  148.  
  149. {
  150.     register int vnum;    /* ordinal number of var refrenced */
  151.     register int status;    /* status return */
  152.     register int vtype;    /* type of variable to set */
  153.     register char * sp;    /* scratch string pointer */
  154.     char var[NVSIZE+1];    /* name of variable to fetch */
  155.     char value[NSTRING];    /* value to set variable to */
  156.  
  157.     /* first get the variable to set.. */
  158.     if (clexec == FALSE) {
  159.         status = mlreply("Variable to set: ", &var[0], NVSIZE);
  160.         if (status != TRUE)
  161.             return(status);
  162.     } else {    /* macro line argument */
  163.         /* grab token and skip it */
  164.         execstr = token(execstr, var);
  165.     }
  166.  
  167.     /* check the legality and find the var */
  168. sv01:    vtype = -1;
  169.     switch (var[0]) {
  170.  
  171.         case '$': /* check for legal enviromnent var */
  172.             for (vnum = 0; vnum < NEVARS; vnum++)
  173.                 if (strcmp(&var[1], envars[vnum]) == 0) {
  174.                     vtype = TKENV;
  175.                     break;
  176.                 }
  177.             break;
  178.  
  179.         case '%': /* check for existing legal user variable */
  180.             for (vnum = 0; vnum < MAXVARS; vnum++)
  181.                 if (strcmp(&var[1], uv[vnum].u_name) == 0) {
  182.                     vtype = TKVAR;
  183.                     break;
  184.                 }
  185.             if (vnum < MAXVARS)
  186.                 break;
  187.  
  188.             /* create a new one??? */
  189.             for (vnum = 0; vnum < MAXVARS; vnum++)
  190.                 if (uv[vnum].u_name[0] == 0) {
  191.                     vtype = TKVAR;
  192.                     strcpy(uv[vnum].u_name, &var[1]);
  193.                     break;
  194.                 }
  195.             break;
  196.  
  197.         case '&':    /* indirect operator? */
  198.             var[4] = 0;
  199.             if (strcmp(&var[1], "ind") == 0) {
  200.                 /* grab token, and eval it */
  201.                 execstr = token(execstr, var);
  202.                 strcpy(var, getval(var));
  203.                 goto sv01;
  204.             }
  205.     }
  206.  
  207.     /* if its not legal....bitch */
  208.     if (vtype == -1) {
  209.         mlwrite("%%No such variable");
  210.         return(FALSE);
  211.     }
  212.  
  213.     /* get the value for that variable */
  214.     if (f == TRUE)
  215.         strcpy(value, itoa(n));
  216.     else {
  217.         status = mlreply("Value: ", &value[0], NSTRING);
  218.         if (status != TRUE)
  219.             return(status);
  220.     }
  221.  
  222.     /* and set the appropriate value */
  223.     status = TRUE;
  224.     switch (vtype) {
  225.     case TKVAR: /* set a user variable */
  226.         if (uv[vnum].u_value != NULL)
  227.             free(uv[vnum].u_value);
  228.         sp = malloc(strlen(value) + 1);
  229.         if (sp == NULL)
  230.             return(FALSE);
  231.         strcpy(sp, value);
  232.         uv[vnum].u_value = sp;
  233.         break;
  234.  
  235.     case TKENV: /* set an environment variable */
  236.         status = TRUE;    /* by default */
  237.         switch (vnum) {
  238.         case EVFILLCOL:    fillcol = atoi(value);
  239.                 break;
  240.         case EVPAGELEN:    status = newsize(TRUE, atoi(value));
  241.                 break;
  242.         case EVCURCOL:    status = setccol(atoi(value));
  243.                 break;
  244.         case EVCURLINE:    status = gotoline(TRUE, atoi(value));
  245.                 break;
  246.         case EVRAM:    break;
  247.         case EVFLICKER:    flickcode = stol(value);
  248.                 break;
  249.         case EVCURWIDTH:status = newwidth(TRUE, atoi(value));
  250.                 break;
  251.         case EVCBUFNAME:strcpy(curbp->b_bname, value);
  252.                 curwp->w_flag |= WFMODE;
  253.                 break;
  254.         case EVCFNAME:    strcpy(curbp->b_fname, value);
  255.                 curwp->w_flag |= WFMODE;
  256.                 break;
  257.         case EVSRES:    status = TTrez(value);
  258.                 break;
  259.         case EVDEBUG:    macbug = stol(value);
  260.                 break;
  261.         case EVSTATUS:    cmdstatus = stol(value);
  262.                 break;
  263.         case EVPALETTE:    strncpy(palstr, value, 48);
  264.                 spal(palstr);
  265.                 break;
  266.         }
  267.         break;
  268.     }
  269.     return(status);
  270. }
  271.  
  272. /*    atoi:    ascii string to integer......This is too
  273.         inconsistant to use the system's    */
  274.  
  275. atoi(st)
  276.  
  277. char *st;
  278.  
  279. {
  280.     int result;    /* resulting number */
  281.     int sign;    /* sign of resulting number */
  282.     char c;        /* current char being examined */
  283.  
  284.     result = 0;
  285.     sign = 1;
  286.     while ((c = *st++)) {
  287.         if (c == '-')
  288.             sign *= -1;
  289.         if (c >= '0' && c <= '9')
  290.             result = result * 10 + c - '0';
  291.     }
  292.  
  293.     return(result * sign);
  294. }
  295.  
  296. /*    itoa:    integer to ascii string.......... This is too
  297.         inconsistant to use the system's    */
  298.  
  299. char *itoa(i)
  300.  
  301. int i;    /* integer to translate to a string */
  302.  
  303. {
  304.     register int digit;        /* current digit being used */
  305.     register char *sp;        /* pointer into result */
  306.     register int sign;        /* sign of resulting number */
  307.     static char result[INTWIDTH+1];    /* resulting string */
  308.  
  309.     /* eliminate the trivial 0 */
  310.     if (i == 0)
  311.         return("0");
  312.  
  313.     /* record the sign...*/
  314.     sign = 1;
  315.     if (i < 0) {
  316.         sign = -1;
  317.         i = -i;
  318.     }
  319.  
  320.     /* and build the string (backwards!) */
  321.     sp = result + INTWIDTH;
  322.     *sp = 0;
  323.     while (i) {
  324.         digit = i % 10;
  325.         *(--sp) = '0' + digit;    /* and install the new digit */
  326.         i = i / 10;
  327.     }
  328.  
  329.     /* and fix the sign */
  330.     if (sign == -1) {
  331.         *(--sp) = '-';    /* and install the minus sign */
  332.     }
  333.  
  334.     return(sp);
  335. }
  336.  
  337. int gettyp(token)    /* find the type of a passed token */
  338.  
  339. char *token;    /* token to analyze */
  340.  
  341. {
  342.     register char c;    /* first char in token */
  343.  
  344.     /* grab the first char (this is all we need) */
  345.     c = *token;
  346.  
  347.     /* no blanks!!! */
  348.     if (c == 0)
  349.         return(TKNUL);
  350.  
  351.     /* a numeric literal? */
  352.     if (c >= '0' && c <= '9')
  353.         return(TKLIT);
  354.  
  355.     switch (c) {
  356.         case '"':    return(TKSTR);
  357.  
  358.         case '!':    return(TKDIR);
  359.         case '@':    return(TKARG);
  360.         case '#':    return(TKBUF);
  361.         case '$':    return(TKENV);
  362.         case '%':    return(TKVAR);
  363.         case '&':    return(TKFUN);
  364.         case '*':    return(TKLBL);
  365.  
  366.         default:    return(TKCMD);
  367.     }
  368. }
  369.  
  370. char *getval(token)    /* find the value of a token */
  371.  
  372. char *token;        /* token to evaluate */
  373.  
  374. {
  375.     register int status;    /* error return */
  376.     register BUFFER *bp;    /* temp buffer pointer */
  377.     register int blen;    /* length of buffer argument */
  378.     char buf[NSTRING];    /* string buffer for some returns */
  379.  
  380.     switch (gettyp(token)) {
  381.         case TKNUL:    return("");
  382.  
  383.         case TKARG:    /* interactive argument */
  384.                 status = getstring(getval(&token[1]),
  385.                        buf, NSTRING, ctoec('\n'));
  386.                 if (status == ABORT)
  387.                     return(errorm);
  388.                 return(buf);
  389.  
  390.         case TKBUF:    /* buffer contents fetch */
  391.  
  392.                 /* grab the right buffer */
  393.                 bp = bfind(getval(&token[1]), FALSE, 0);
  394.                 if (bp == NULL)
  395.                     return(errorm);
  396.         
  397.                 /* make sure we are not at the end */
  398.                 if (bp->b_linep == bp->b_dotp)
  399.                     return(errorm);
  400.         
  401.                 /* grab the line as an argument */
  402.                 blen = bp->b_dotp->l_used;
  403.                 if (blen > NSTRING)
  404.                     blen = NSTRING;
  405.                 strncpy(buf, bp->b_dotp->l_text, blen);
  406.                 buf[blen] = 0;
  407.         
  408.                 /* and step the buffer's line ptr ahead a line */
  409.                 bp->b_dotp = bp->b_dotp->l_fp;
  410.                 bp->b_doto = 0;
  411.  
  412.                 /* and return the spoils */
  413.                 return(buf);        
  414.  
  415.         case TKVAR:    return(gtusr(token+1));
  416.         case TKENV:    return(gtenv(token+1));
  417.         case TKFUN:    return(gtfun(token+1));
  418.         case TKDIR:    return(errorm);
  419.         case TKLBL:    return(itoa(gtlbl(token)));
  420.         case TKLIT:    return(token);
  421.         case TKSTR:    return(token+1);
  422.         case TKCMD:    return(token);
  423.     }
  424. }
  425.  
  426. gtlbl(token)    /* find the line number of the given label */
  427.  
  428. char *token;    /* label name to find */
  429.  
  430. {
  431.     return(1);
  432. }
  433.  
  434. int stol(val)    /* convert a string to a numeric logical */
  435.  
  436. char *val;    /* value to check for stol */
  437.  
  438. {
  439.     /* check for logical values */
  440.     if (val[0] == 'F')
  441.         return(FALSE);
  442.     if (val[0] == 'T')
  443.         return(TRUE);
  444.  
  445.     /* check for numeric truth (!= 0) */
  446.     return((atoi(val) != 0));
  447. }
  448.  
  449. char *ltos(val)        /* numeric logical to string logical */
  450.  
  451. int val;    /* value to translate */
  452.  
  453. {
  454.     if (val)
  455.         return(truem);
  456.     else
  457.         return(falsem);
  458. }
  459.